package experiment.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import com.google.code.microlog4android.Logger;
import com.google.code.microlog4android.LoggerFactory;

/**
 * 
 * @author kuehnel.christine
 * parsing of VPx.xml file
 */

// Format:
// <?xml version="1.0" encoding="utf-8"?>
//	<config blocks="5" runs="5" numbers="20">
//	<block nr="1" feedback="none">
//		<run nr="1" sdf="0">
//			<numbers>1234,5678</numbers>
//		</run>
//	</block>
// </config>

public class ExpConfigHandler extends org.xml.sax.helpers.DefaultHandler{
	
	private static final Logger logger = LoggerFactory.getLogger();
	
	private boolean in_numbers = false;
	
	private ExpParsedConfigDataSet myExpParsedConfigDataSet;
	
	int blocks = 0;
	int runs = 0;
	int numbers = 0;
	int blockNr = 0;
	int runNr = 0;
	
    TimeZone tz = TimeZone.getTimeZone("Europe/Berlin");
    Locale locale = Locale.GERMANY;
    final Calendar c = Calendar.getInstance(tz,locale);
	
	public ExpConfigHandler(ExpParsedConfigDataSet myExpParsedConfigDataSet){
		this.myExpParsedConfigDataSet = myExpParsedConfigDataSet;
	}

	public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {

		/**
         * <config blocks="5" runs="5" numbers="20">
         */ 
		if (localName.equals("config")) {
			// get total number of blocks
            String blocksValue = atts.getValue("blocks");
            blocks = Integer.parseInt(blocksValue);
            
			// get total number of runs
            String runsValue = atts.getValue("runs");
            runs = Integer.parseInt(runsValue);
            
			// get total number of numbers
            String numbersValue = atts.getValue("numbers");
            numbers = Integer.parseInt(numbersValue);
            
            myExpParsedConfigDataSet.setNumberOfBlocks(blocks);
            myExpParsedConfigDataSet.setNumberOfRuns(runs);
            myExpParsedConfigDataSet.setNumberOfNumbers(numbers);
            
            //logger.info("* " + blocks + " blocks, " + runs + " runs, " + numbers + " numbers");
            logger.info("* 7  blocks,  80 runs, 560 numbers");
		}
        /**
         * <block nr="" feedback="">    
         */
		else if (localName.equals("block")) {
			
			// get block number
            String nrValue = atts.getValue("nr");
            blockNr = Integer.parseInt(nrValue);
            
            // get feedbackmodality
            String fbModality = atts.getValue("feedback");            

            ArrayList<String> tmpBlockArray = myExpParsedConfigDataSet.getBlockArray();
            if(tmpBlockArray == null){
            	tmpBlockArray = new ArrayList<String>();
            }
            
            tmpBlockArray.add(blockNr-1,fbModality);
            myExpParsedConfigDataSet.setBlockArray(tmpBlockArray);
		}   
        /**
         * <run nr="1" sdf="0">    
         */
		else if (localName.equals("run")) {
			
			// get run number
            String nrValue = atts.getValue("nr");
            runNr = Integer.parseInt(nrValue);
            
            // get feedback modality
            String sfdValue = atts.getValue("sfd");
            int sfd = Integer.parseInt(sfdValue);
            

            ArrayList<ArrayList<Integer>> tmpRunArray = myExpParsedConfigDataSet.getRunArray();
            ArrayList<Integer> tmpRunArray2;
            if(tmpRunArray == null){
            	tmpRunArray = new ArrayList<ArrayList<Integer>>();
            	tmpRunArray2 = new ArrayList<Integer>();
                tmpRunArray2.add(runNr-1,sfd);
                tmpRunArray.add(blockNr-1,tmpRunArray2);
            }else
            {
            	if(tmpRunArray.size() < blockNr){
            		tmpRunArray2 = new ArrayList<Integer>();
            		tmpRunArray2.add(runNr-1,sfd);
                    tmpRunArray.add(blockNr-1,tmpRunArray2);            		
            	}else{
                	tmpRunArray2 = tmpRunArray.get(blockNr-1);
            		tmpRunArray2.add(runNr-1,sfd);
            		tmpRunArray.set(blockNr-1,tmpRunArray2);
            	}
            }
            myExpParsedConfigDataSet.setRunArray(tmpRunArray);

		}else if (localName.equals("numbers")) {
			
			this.in_numbers = true;
		}
	}
	
	public void endElement(String namespaceURI, String localName, String qName)throws SAXException {
		if (localName.equals("config")){
			if(blockNr != blocks)
				logger.error("* " + "falsche Anzahl Bloecke: " + blockNr + " statt " + blocks);
			
			logger.info("* " + "feedback: " + myExpParsedConfigDataSet.getBlockArray().toString());
			//logger.info("* " + "SFD: " + myExpParsedConfigDataSet.getRunArray().toString());
			logger.info("* " + "Pins: " + myExpParsedConfigDataSet.getNumberArray().toString());
			
			logger.info("********** HEADER **********");
	        
			SimpleDateFormat f= new SimpleDateFormat("dd.MM.yyyy hh:mm");
	        f.setTimeZone(c.getTimeZone());
	        Date date = c.getTime();
        	
	        logger.info("Anfang des 1  Blocks " + f.format(date));
        	logger.info("--------------------------------");
				
		}else if (localName.equals("block")){
			if(runNr != runs)
				logger.error("In Block " + blockNr + " falsche Anzahl Durchgaenge: " + runNr + " statt " + runs);			
		}else 
			if (localName.equals("numbers")) {
	    	this.in_numbers = false;

	    }
    }
	
	/** Gets be called on the following structure:
	  * <tag>characters</tag> 
	  * writes to an array[blocks] of an array[runs] of an array[numbers]: [[[][][][][]] [[]...[]] ...]
	**/
	   
	@Override
	public void characters(char ch[], int start, int length) {
        /**
         * <numbers>1234,5678</numbers>    
         */
        if(this.in_numbers){
        	String numberStr = new String(ch, start, length);
        	String[] numbersArray = numberStr.split(",");
        	// holds Numbers
            ArrayList<String> tmpArray1 = new ArrayList<String>();
            // holds array of numbers for each run
            ArrayList<ArrayList<String>> tmpArray2; 
            // holds array of runs for each block
            ArrayList<ArrayList<ArrayList<String>>> tmpArray3;

            // write innermost array of numbers
            if(numbersArray.length != numbers)
            {
             logger.error("falsche Anzahl Nummern: " + numbersArray.length + " statt " + numbers);
            }
        	for(int i=0;i<numbersArray.length;i++){
        		tmpArray1.add(i,numbersArray[i]);
        	}
        	
        	// write middle array of runs
        	tmpArray3 = myExpParsedConfigDataSet.getNumberArray();
            if(tmpArray3 == null){
            	tmpArray2 = new ArrayList<ArrayList<String>>();
            	tmpArray3 = new ArrayList<ArrayList<ArrayList<String>>>();
            	tmpArray2.add(runNr-1,tmpArray1);            	
                tmpArray3.add(blockNr-1,tmpArray2);
            }else
            {
            	if(tmpArray3.size() < blockNr){
            		tmpArray2 = new ArrayList<ArrayList<String>>();
                	tmpArray2.add(runNr-1,tmpArray1);            	
                    tmpArray3.add(blockNr-1,tmpArray2);
            	}else{
                	tmpArray2 = tmpArray3.get(blockNr-1);
                	tmpArray2.add(runNr-1,tmpArray1);            	
                    tmpArray3.set(blockNr-1,tmpArray2);            		
            	}
            }           
            myExpParsedConfigDataSet.setNumberArray(tmpArray3);        	
        }
	   
	}
	   
	public void startDocument() throws SAXException {
		   
		// Do some startup if needed
	   
	}

}
